﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using thailandProject.Models;
using thailandProject.ViewModel;
using MvcFilters.Infrastructure.Filters;

namespace thailandProject.Controllers
{
    [ThailandAuthorize(1)]
    public class AdminController : Controller
    {
        //
        // GET: /Admin/

        public ActionResult Index()
        {
            try
            {
                ViewBag.Header = "Administrator";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        // manage clients
        [HttpGet]
        public ActionResult ManageClients()
        {
            try
            {
                ViewBag.Header = "Manage Clients";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(-1);    //-1 to hide "X clients deleted"
        }

        [HttpPost]
        public ActionResult ManageClients(string days)
        {
            int clientsDeleted = 0;
            try
            {
                ViewBag.Header = "Manage Clients";

                int numDays = Convert.ToInt32(days);

                ThailandEntities a = new ThailandEntities();

                //Select all clients who should be deleted
                DateTime date = DateTime.Now.AddDays(numDays * -1);

                //Select every single reservation that is confirmed
                //Then, select every client that did not appear in the list AND
                //was added before the delete date
                var clients = from client in a.CLIENTs
                              where !(from reservation in a.RESERVATIONs
                                      where reservation.resIsHeld == false
                                      select reservation.clientID).Contains(client.clientID) &&
                              client.clientDateCreated < date
                              select client;

                List<CLIENT> delClients = clients.ToList();
                clientsDeleted = delClients.Count();

                foreach (CLIENT c in delClients)
                {
                    //Cascade delete everything that has a tie to this particular client
                    var cps = from cp in a.CLIENTPHONEs
                              where cp.clientID == c.clientID
                              select cp;
                    List<CLIENTPHONE> cPhones = cps.ToList();

                    foreach (CLIENTPHONE cp in cPhones)
                        a.DeleteObject(cp);

                    //Delete the reservations
                    var rs = from r in a.RESERVATIONs
                             where r.clientID == c.clientID
                             select r;
                    List<RESERVATION> res = rs.ToList();

                    foreach (RESERVATION r in res)
                    {
                        //Delete the reservation's payments and tasks
                        var ps = from p in a.PAYMENTs
                                 where p.resID == r.resID
                                 select p;
                        List<PAYMENT> pay = ps.ToList();

                        foreach (PAYMENT p in pay)
                            a.DeleteObject(p);

                        var ts = from t in a.TASKs
                                 where t.resID == r.resID
                                 select t;
                        List<TASK> task = ts.ToList();

                        foreach (TASK t in task)
                            a.DeleteObject(t);

                        a.DeleteObject(r);
                    }
                    
                    //Delete the emails sent
                    var em = from e in a.EMAILSENTs
                             where e.clientID == c.clientID
                             select e;
                    List<EMAILSENT> email = em.ToList();

                    foreach (EMAILSENT e in email)
                        a.DeleteObject(e);

                    //Finally, delete the client
                    a.DeleteObject(c);
                }//End to foreach client
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(clientsDeleted);     //Return the number of clients deleted
        }

        // general management of properties
        public ActionResult ManageProperties()
        {
            List<PROPERTY> result = new List<PROPERTY>();
            try
            {
                ViewBag.Header = "Manage Properties";

                ThailandEntities a = new ThailandEntities();
                var properties = from property in a.PROPERTies
                                 orderby property.propName
                                 select property;
                result = properties.ToList();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(result);
        }

        // Gets the initial AddProperty page
        [HttpGet]
        public ActionResult AddProperty()
        {
            try
            {
                ViewBag.Header = "Add Property";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();
        }

        // add a new property
        [HttpPost]
        public ActionResult AddProperty(FormCollection data)
        {
            PROPERTY newProp = new PROPERTY();
            try
            {
                //Due to the checkboxes, a PROPERTY object can't be used
                newProp.propDetails = data["propDetails"].ToString();
                newProp.propHyperlink = data["propHyperlink"].ToString();
                newProp.propLocation = data["propLocation"].ToString();
                newProp.propName = data["propName"].ToString();
                newProp.propIsActive = true; //By default, it's active
                //Ugh, that was painful to type all that....

                ViewBag.Header = "View Property";
                ThailandEntities c = new ThailandEntities();
                c.PROPERTies.AddObject(newProp);
                int change = c.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            // pass back the object and send to viewProperty
            //return View("ViewAllProperties", PropertyMatch.getPropertiesFromIds(propertyID));
            //return View("viewallproperties", "");
            //return View("EditProperty", prop);
            return RedirectToAction("ViewProperty", "Property", newProp);
        }

        // edit an existing property
        [HttpGet]
        public ActionResult EditProperty(int propId)
        {
            PROPERTY prop = new PROPERTY();
            try
            {
                ViewBag.Header = "Edit Property";

                ThailandEntities a = new ThailandEntities();

                var properties = from property in a.PROPERTies
                                 where property.propID == propId
                                 select property;
                prop = properties.ToList()[0];
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            // pass back the object and send to viewProperty
            //return View("ViewAllProperties", PropertyMatch.getPropertiesFromIds(propertyID));
            //return View("viewallproperties", "");
            return View(prop);
        }

        // edit an existing property
        [HttpPost]
        public ActionResult EditProperty(PROPERTY prop)
        {
            try
            {
                ViewBag.Header = "Edit Property";

                ThailandEntities a = new ThailandEntities();

                a.PROPERTies.AddObject(prop);
                a.ObjectStateManager.ChangeObjectState(prop, System.Data.EntityState.Modified);
                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ViewProperty", "Property", prop);
        }


        [HttpGet]
        public ActionResult DeactivateProperty(int propId)
        {
            //Delete this property and return to the ManageProperties page
            try
            {
                //Select the property
                ThailandEntities a = new ThailandEntities();

                var props = from prop in a.PROPERTies
                            where prop.propID == propId
                            select prop;
                PROPERTY deactiveProp = props.ToList()[0];

                
                //Deactivate the property
                deactiveProp.propIsActive = false;
                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ManageProperties");
        }
                
        [HttpGet]
        public ActionResult DeleteProperty(int propId)
        {
            //Delete this property and return to the ManageProperties page
            try
            {
                //Select the property
                ThailandEntities a = new ThailandEntities();

                var props = from prop in a.PROPERTies
                            where prop.propID == propId
                            select prop;
                PROPERTY delProp = props.ToList()[0];

                //Select all associated reservations
                var ress = from res in a.RESERVATIONs
                           where res.propID == delProp.propID
                           select res;
                List<RESERVATION> delRes = ress.ToList();

                //Delete all reservations
                foreach (RESERVATION r in delRes)
                {
                    //Delete all associated payments
                    var payments = from payment in a.PAYMENTs
                                   where payment.resID == r.resID
                                   select payment;
                    List<PAYMENT> delPay = payments.ToList();

                    //Delete the payments
                    foreach (PAYMENT p in delPay)
                        a.DeleteObject(p);

                    //Select all associated tasks
                    var tasks = from task in a.TASKs
                                where task.resID == r.resID
                                select task;
                    List<TASK> delTask = tasks.ToList();

                    //Delete the tasks
                    foreach (TASK t in delTask)
                        a.DeleteObject(t);

                    //Finally, delete this reservation
                    a.DeleteObject(r);
                }

                //Delete the property now that it has no children
                a.DeleteObject(delProp);

                int change = a.SaveChanges();
            }
            catch (Exception e)
            {
                ErrorLog.logError(e);
            }

            return RedirectToAction("ManageProperties");
        }

        [HttpGet]
        public ActionResult ManageTaskTypes()
        {
            List<TASKTYPE> tasks = new List<TASKTYPE>();
            try
            {
                ViewBag.Header = "Manage Task Types";

                ThailandEntities a = new ThailandEntities();

                var taskTypes = from taskType in a.TASKTYPEs
                                where taskType.taskTypeID > 0
                                orderby taskType.taskTypeName
                                select taskType;
                tasks = taskTypes.ToList();
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }

            return View(tasks);
        }

        [HttpGet]
        public ActionResult AddTaskType()
        {
            try
            {
                ViewBag.Header = "Add Task Type";
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }

            return View();
        }

        [HttpPost]
        public ActionResult AddTaskType(FormCollection data)
        {
            try
            {
                ViewBag.Header = "Manage Task Types";

                TASKTYPE newType = new TASKTYPE();
                newType.taskTypeName = data["taskTypeName"].ToString();
                newType.isActive = true;

                ThailandEntities a = new ThailandEntities();
                a.TASKTYPEs.AddObject(newType);

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }

            return RedirectToAction("ManageTaskTypes");
        }

        [HttpGet]
        public ActionResult EditTaskType(int taskTypeId)
        {
            TASKTYPE task = new TASKTYPE();
            try
            {
                ViewBag.Header = "Add Task Type";

                ThailandEntities a = new ThailandEntities();

                var taskTypes = from taskType in a.TASKTYPEs
                                where taskType.taskTypeID == taskTypeId
                                select taskType;
                task = taskTypes.ToList()[0];
            }
            catch (Exception ex)
            {
                ErrorLog.logError(ex);
            }

            return View(task);
        }

        [HttpGet]
        public ActionResult DeleteTaskType(int taskTypeId)
        {
            //Delete the task type and redirect to ManageTaskTypes
            try
            {
                //Select the task type
                ThailandEntities a = new ThailandEntities();

                var tts = from tt in a.TASKTYPEs
                          where tt.taskTypeID == taskTypeId
                          select tt;
                TASKTYPE delTT = tts.ToList()[0];

                //Select all associated tasks
                var tasks = from task in a.TASKs
                            where task.taskTypeID == delTT.taskTypeID
                            select task;
                List<TASK> delTasks = tasks.ToList();

                //Delete each task with this task type
                foreach (TASK t in delTasks)
                    a.DeleteObject(t);

                //Delete the task type
                a.DeleteObject(delTT);

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ManageTaskTypes");
        }

        [HttpPost]
        public ActionResult EditTaskType(FormCollection data)
        {
            try
            {
                ViewBag.Header = "Manage Task Types";

                TASKTYPE editType = new TASKTYPE();
                editType.taskTypeID = Convert.ToInt32(data["taskTypeID"].ToString());
                editType.taskTypeName = data["taskTypeName"].ToString();
                editType.isActive = data["isActive"] != null ? true : false;

                ThailandEntities a = new ThailandEntities();
                a.TASKTYPEs.AddObject(editType);
                a.ObjectStateManager.ChangeObjectState(editType, System.Data.EntityState.Modified);

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ManageTaskTypes");
        }

        [HttpGet]
        public ActionResult ManageUsers()
        {
            List<USER> usersResult = new List<USER>();
            try
            {
                ViewBag.Header = "Manage Users";

                ThailandEntities a = new ThailandEntities();

                var users = from user in a.USERs
                            orderby user.userFirstName, user.userLastName
                            select user;
                usersResult = users.ToList();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(usersResult);
        }

        [HttpGet]
        public ActionResult AddUser()
        {
            try
            {
                ViewBag.Header = "Add User";
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View();

        }

        [HttpPost]
        public ActionResult AddUser(FormCollection data)
        {
            try
            {
                ViewBag.Header = "Manage Users";

                ThailandEntities a = new ThailandEntities();

                //Create the user first
                USER newUser = new USER();
                newUser.isActive = true;
                newUser.userEmail = data["userEmail"].ToString();
                newUser.userFirstName = data["userFirstName"].ToString();
                newUser.userLastName = data["userLastName"].ToString();
                newUser.username = data["username"].ToString();
                newUser.userPassword = data["userPassword"].ToString();

                
                newUser.permID = Convert.ToInt32(data["permID"]);

                a.USERs.AddObject(newUser);

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ManageUsers");
        }

        [HttpGet]
        public ActionResult EditUser(int userId)
        {
            USER userResult = new USER();
            try
            {
                ViewBag.Header = "Edit User";

                ThailandEntities a = new ThailandEntities();

                var users = from user in a.USERs
                            where user.userID == userId
                            select user;
                userResult = users.ToList()[0];
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(userResult);
        }

        [HttpPost]
        public ActionResult EditUser(FormCollection data)
        {
            try
            {
                ViewBag.Header = "Manage Users";

                using(ThailandEntities a = new ThailandEntities())
                {
                    int userID = userID = Convert.ToInt32(data["userID"]);
                    var users = from user in a.USERs
                                where user.userID == userID
                                select user;

                //Create the user first
                USER editUser = users.ToList()[0];

                editUser.userID = Convert.ToInt32(data["userID"]);
                editUser.isActive = data["isActive"] != null ? true : false;
                editUser.userEmail = data["userEmail"].ToString();
                editUser.userFirstName = data["userFirstName"].ToString();
                editUser.userLastName = data["userLastName"].ToString();
                editUser.username = data["username"].ToString();
                editUser.userPassword = data["userPassword"].ToString();

                //Create the userPerm object first
                editUser.permID = Convert.ToInt32(data["permID"]);

                int change = a.SaveChanges();
                }                
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return RedirectToAction("ManageUsers");
        }

        [HttpGet]
        [ThailandAuthorize(1, null, new int[] { -1 })]
        public ActionResult DeleteUser(int userId)
        {
            //Delete the user with this ID
            try
            {
                //Make sure the user hasn't manually typed his id into the address bar
                if (((USER)Session["user"]).userID == userId)
                    return RedirectToAction("ManageUsers");
                
                ThailandEntities a = new ThailandEntities();
                var users = from user in a.USERs
                            where user.userID == userId
                            select user;
                USER delUser = users.ToList()[0];

                //Delete this user's email preferences
                var prefs = from pref in a.EMAILPREFERENCEs
                            where pref.userID == delUser.userID
                            select pref;
                if(prefs.Count() > 0)
                    a.DeleteObject(prefs.ToList()[0]);

                //Delete all of the cookies that relate to this user
                var cookies = from cookie in a.COOKIEs
                              where cookie.userID == delUser.userID
                              select cookie;
                foreach (COOKIE c in cookies.ToList())
                    a.DeleteObject(c);

                //Delete all reservations this user has made
                var ress = from res in a.RESERVATIONs
                           where res.userID == delUser.userID
                           select res;
                foreach (RESERVATION r in ress.ToList())
                {
                    //Delete all tasks associated with this reservation
                    var tasks = from task in a.TASKs
                                where task.resID == r.resID
                                select task;
                    foreach (TASK t in tasks.ToList())
                        a.DeleteObject(t);

                    //Delete all payments associated with this reservation
                    var pays = from pay in a.PAYMENTs
                               where pay.resID == r.resID
                               select pay;
                    foreach (PAYMENT p in pays.ToList())
                        a.DeleteObject(p);

                    //Finally, delete the reservation
                    a.DeleteObject(r);
                }

                //Now that all ties to this user have been removed, delete it
                a.DeleteObject(delUser);

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return RedirectToAction("ManageUsers");
        }

        [HttpGet]
        [ThailandAuthorize(1, null, new int[] { -1 })]
        public ActionResult EmailPreferences()
        {
            EMAILPREFERENCE rt = null;
            try
            {
                ViewBag.Header = "Edit Email Preferences";

                ThailandEntities a = new ThailandEntities();

                int userID = ((USER)Session["user"]).userID;

                var prefs = from pref in a.EMAILPREFERENCEs
                            where pref.userID == userID
                            select pref;

                int richardUserID = 1;
                var prefs2 = from pref in a.EMAILPREFERENCEs
                                   where pref.userID == richardUserID
                                   select pref;

                List<EMAILPREFERENCE> userPref = prefs.ToList();
                List<EMAILPREFERENCE> richardPref = prefs2.ToList();

                if (userPref.Count == 0)
                {
                    //If this user has no email preferences, make them a default one
                    rt = new EMAILPREFERENCE();
                    rt.userID = userID;
                    if (richardPref.Count != 0)
                    {
                        rt.gmailUserName = richardPref[0].gmailUserName;
                        rt.gmailPassword = richardPref[0].gmailPassword;
                    }
                    else
                    {
                        rt.gmailPassword = "";
                        rt.gmailUserName = "";
                    }
                    rt.onDeposityMade = true;
                    rt.onPropInquiry = true;
                    rt.onRefundMade = false;
                    rt.onReservationDrop = true;
                    rt.onReservationEdit = true;

                    //Add it to the database
                    a.EMAILPREFERENCEs.AddObject(rt);
                    int change = a.SaveChanges();
                }
                else
                {
                    //Use the one provided in the database
                    rt = userPref[0];

                    // return Rich's Gmail Username and password not the current users
                    if (richardPref.Count != 0)
                    {
                        rt.gmailUserName = richardPref[0].gmailUserName;
                        rt.gmailPassword = richardPref[0].gmailPassword;
                    }
                    else
                    {
                        rt.gmailPassword = "";
                        rt.gmailUserName = "";
                    }
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            

            return View(new Pair<EMAILPREFERENCE, bool>(rt, false));
        }

        [HttpPost]
        [ThailandAuthorize(1, null, new int[] { -1 })]
        public ActionResult EmailPreferences(FormCollection data)
        {
            EMAILPREFERENCE edit = new EMAILPREFERENCE();
            try
            {
                ViewBag.Header = "Edit Email Preferences";

                ThailandEntities a = new ThailandEntities();
                ThailandEntities b = new ThailandEntities();

                int richardUserID = 1;
                var prefs2 = from pref in b.EMAILPREFERENCEs
                             where pref.userID == richardUserID
                             select pref;

                List<EMAILPREFERENCE> richardPref = prefs2.ToList();
                
                bool gmailChanged = (!data["gmailPassword"].ToString().Equals(richardPref[0].gmailPassword) ||
                        !data["gmailUserName"].ToString().Equals(richardPref[0].gmailUserName));

                edit.userID = Convert.ToInt32(data["userID"].ToString());
                edit.gmailPassword = data["gmailPassword"].ToString();
                edit.gmailUserName = data["gmailUserName"].ToString();
                edit.onDeposityMade = data["onDepositMade"] != null ? true : false;
                edit.onPropInquiry = data["onPropInquiry"] != null ? true : false;
                edit.onRefundMade = data["onRefundMade"] != null ? true : false;
                edit.onReservationDrop = data["onReservationDrop"] != null ? true : false;
                edit.onReservationEdit = data["onReservationEdit"] != null ? true : false;

                a.EMAILPREFERENCEs.AddObject(edit);
                a.ObjectStateManager.ChangeObjectState(edit, System.Data.EntityState.Modified);

                int change = a.SaveChanges();

                // send email if email address has changed
                if (gmailChanged)
                {
                    // If the user we were modifying is not Richard Katze then
                    //  Modify Richard Katze's email address
                    if ((edit.userID != richardUserID) &&
                        (richardPref.Count != 0))
                    {
                        EMAILPREFERENCE richUserPref = richardPref[0];
                        // The Gmail Username or password has been changed
                        richUserPref.gmailUserName = data["gmailUserName"].ToString();
                        richUserPref.gmailPassword = data["gmailPassword"].ToString();

                        change = b.SaveChanges();
                    }

                    // Now send an email notifying Rich that his email has been changed.

                    String emailMessage = "congratulations your account has been successfully updated to use the following information\n\n" +
                                            "Username: " + edit.gmailUserName.ToString() +
                                            "\n\nI hope you enjoy sending emails using your new email address";

                    bool sendSuccess = GMailer.SendMail("Your Account has been Updated", edit.gmailUserName.ToString() + "@gmail.com", emailMessage);
                    if (!sendSuccess)
                    {
                        // The Given Username or Password is not valid, please enter a new one.
                        //  This could also error if a firewall was blocking SNMP traffic
                    }
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }            

            return View(new Pair<EMAILPREFERENCE, bool>(edit, true));
        }

        [HttpGet]
        [ThailandAuthorize(1, null, new int[] { -1 })]
        public ActionResult EditEmailTemplate(string type)
        {
            //Get the current user's EmailPreferences
            string rt = "";
            try
            {
                EMAILPREFERENCE pref = EmailController.getPreferences(1);//getPreferences(((USER)Session["user"]).userID);

                switch (type)
                {
                    case "onDepositMade":
                        if (String.IsNullOrEmpty(pref.onDepositMadeTemplate))
                            rt = EmailTemplateModel.defaultOnDepositMade();
                        else
                            rt = pref.onDepositMadeTemplate;
                        break;
                    case "onRefundMade":
                        if (String.IsNullOrEmpty(pref.onRefundMadeTemplate))
                            rt = EmailTemplateModel.defaultOnRefundMade();
                        else
                            rt = pref.onRefundMadeTemplate;
                        break;
                    case "onReservationDrop":
                        if (String.IsNullOrEmpty(pref.onReservationDropTemplate))
                            rt = EmailTemplateModel.defaultOnReservationDrop();
                        else
                            rt = pref.onReservationDropTemplate;
                        break;
                    case "onPropInquiry":
                        if (String.IsNullOrEmpty(pref.onPropInquiryTemplate))
                            rt = EmailTemplateModel.defaultOnPropInquiry();
                        else
                            rt = pref.onPropInquiryTemplate;
                        break;
                    case "onReservationEdit":
                        if (String.IsNullOrEmpty(pref.onReservationEditTemplate))
                            rt = EmailTemplateModel.defaultOnReservationEdit();
                        else
                            rt = pref.onReservationEditTemplate;
                        break;
                    default: rt = EmailTemplateModel.defaultOnError(); break;
                }
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            EmailTemplateModel etm = new EmailTemplateModel(type, rt);

            return View(etm);
        }

        [HttpPost]
        [ThailandAuthorize(1, null, new int[] { -1 })]
        public ActionResult EditEmailTemplate(FormCollection data)
        {
            try
            {
                string[] values = data["values"].Split('}');
                string[] keys = data["keys"].Split(',');
                string templateType = data["templateType"];

                //Generate the XML string
                string html = "<Template>";

                for (int i = 0; i < keys.Length; i++)
                {
                    if (i > 0)
                        values[i] = values[i].Substring(1); //There will be an extra comma. Remove it

                    html += "<Tag>" +
                                "<Name>" + keys[i] + "</Name>" +
                                "<Value>" + values[i] + "</Value>" +
                            "</Tag>";
                }

                html += "</Template>";

                //Store this in the database
                ThailandEntities a = new ThailandEntities();
                int userID = 1; // ((USER)Session["user"]).userID;

                //Get the email preferences
                var prefs = from pref in a.EMAILPREFERENCEs
                            where pref.userID == userID
                            select pref;
                EMAILPREFERENCE p = prefs.ToList()[0];

                switch (templateType)
                {
                    case "onDepositMade": p.onDepositMadeTemplate = html; break;
                    case "onRefundMade": p.onRefundMadeTemplate = html; break;
                    case "onReservationDrop": p.onReservationDropTemplate = html; break;
                    case "onPropInquiry": p.onPropInquiryTemplate = html; break;
                    case "onReservationEdit": p.onReservationEditTemplate = html; break;
                }

                int change = a.SaveChanges();
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return RedirectToAction("EmailPreferences");
        }

        [HttpGet]
        [ThailandAuthorize(1, new int[] { -1 })]
        public ActionResult ErrorList()
        {
            Pair<List<ERROR>, List<USER>> result = new Pair<List<ERROR>,List<USER>>(new List<ERROR>(), new List<USER>());
            try
            {
                ViewBag.Header = "Error List";

                #region Store Search Terms in Session
                if (Session["elDaysAgo"] == null)
                    Session.Add("elDaysAgo", -1);

                if (Session["elfunctionName"] == null)
                    Session.Add("elfunctionName", "");

                if (Session["eluserID"] == null)
                    Session.Add("eluserID", -1);

                if (Session["elerrorTextContaining"] == null)
                    Session.Add("elerrorTextContaining", "");
                #endregion

                ThailandEntities a = new ThailandEntities();

                var errors = from error in a.ERRORs
                             orderby error.errorTimeStamp descending
                             select error;

                var users = from user in a.USERs
                            orderby user.userID
                            select user;
                result = new Pair<List<ERROR>, List<USER>>(errors.ToList(), users.ToList());
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(result);
        }

        [HttpPost]
        [ThailandAuthorize(1, new int[] { -1 })]
        public ActionResult ErrorList(int daysAgo, string functionName, int userID, string errorTextContaining)
        {
            Pair<List<ERROR>, List<USER>> result = null;
            try
            {
                ViewBag.Header = "Error List";

                //Store the search terms in session
                #region Store Search Terms in Session
                if (Session["elDaysAgo"] == null)
                    Session.Add("elDaysAgo", daysAgo);
                else
                    Session["elDaysAgo"] = daysAgo;

                if (Session["elfunctionName"] == null)
                    Session.Add("elfunctionName", functionName);
                else
                    Session["elfunctionName"] = functionName;

                if (Session["eluserID"] == null)
                    Session.Add("eluserID", userID);
                else
                    Session["eluserID"] = userID;

                if (Session["elerrorTextContaining"] == null)
                    Session.Add("elerrorTextContaining", errorTextContaining);
                else
                    Session["elerrorTextContaining"] = errorTextContaining;
                #endregion

                ThailandEntities a = new ThailandEntities();

                DateTime date = DateTime.MinValue;
                if (daysAgo != -1)
                    date = DateTime.Now.AddDays(daysAgo * -1);

                var errors = from error in a.ERRORs
                             where error.errorTimeStamp >= date &&
                             error.errorFunctionName.Contains(functionName) &&
                             (userID != -1 ? error.userID == userID : true) &&
                             error.errorText.Contains(errorTextContaining)
                             orderby error.errorTimeStamp descending
                             select error;

                var users = from user in a.USERs
                            orderby user.userID
                            select user;
                result = new Pair<List<ERROR>, List<USER>>(errors.ToList(), users.ToList());
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }

            return View(result);
        }

        public ActionResult ErrorDelete(int? errorID)
        {
            try
            {
                if (errorID.HasValue)
                {
                    ThailandEntities a = new ThailandEntities();

                    //A delete request was sent
                    var delErrors = from error in a.ERRORs
                                    where error.errorID == errorID.Value
                                    select error;
                    ERROR delError = delErrors.ToList()[0];

                    a.DeleteObject(delError);
                    int change = a.SaveChanges();
                }//End to if errorID has a value

                return RedirectToAction("ErrorList", new
                {
                    daysAgo = Convert.ToInt32(Session["elDaysAgo"].ToString()),
                    functionName = Session["elfunctionName"].ToString(),
                    userID = Convert.ToInt32(Session["eluserID"].ToString()),
                    errorTextContaining = Session["elerrorTextContaining"].ToString()
                });
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
        }

        public ActionResult ErrorDeleteAll()
        {
            try
            {
                ThailandEntities a = new ThailandEntities();

                //A delete request was sent
                var delErrors = from error in a.ERRORs
                                select error;
                List<ERROR> dErrors = delErrors.ToList();

                foreach(ERROR e in dErrors)
                    a.DeleteObject(e);
                int change = a.SaveChanges();

                return RedirectToAction("ErrorList");
            }
            catch (Exception ex)
            {
                int errorCode = ErrorLog.logError(ex);
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
        }

        /// <summary>
        /// A debug function intended to intentionally create an error to test error logging.
        /// It will redirect to the ErrorLog page
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult GenerateError()
        {
            try
            {
                int a = 0;
                int b = 5 / a;
            }
            catch (Exception e)
            {
                int errorCode = ErrorLog.logError(e, "This is an intentional error for debugging purposes, you can ignore this one.");
                return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
            }
            return RedirectToAction("ErrorList");
        }

        /// <summary>
        /// A debug function intended to intentionally create an error to test error logging.
        /// It will redirect to the ErrorLog page
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult GenerateNestedError()
        {
            try
            {
                int a = 0;
                int b = 5 / a;
            }
            catch (Exception e)
            {
                try
                {
                    throw new Exception("This exception contains one inner exception. Please look at that for more information.", e);
                }
                catch (Exception ee)
                {
                    try
                    {
                        throw new Exception("This is the third Exception to test nested exceptions, There should be two inner exceptions.",ee);
                    }
                    catch (Exception eee)
                    {
                        int errorCode = ErrorLog.logError(eee, "This is an intentional error for debugging purposes, you can ignore this one.");
                        return RedirectToAction("Error", "Home", new { errorID = errorCode + "" });
                    }
                }
            }

            return RedirectToAction("ErrorList");
        }
    }
}
